import Flutter
import UIKit

#if canImport(ThreadNetwork)
import ThreadNetwork

public class ThCredentialsManagerPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: "th_credentials_manager", binaryMessenger: registrar.messenger())
    let instance = ThCredentialsManagerPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    let notSupport = "The system version is too low to support this method"
    let dataError = "Data error"
    switch call.method {
    case "getPlatformVersion":
      result("iOS " + UIDevice.current.systemVersion)
    case "getAllCredentials":
        if #available(iOS 15.0, *) {
            let thClient = THClient()
            Task{
                do {
                    let allCredentials = try await thClient.allCredentials()
                    if(allCredentials.isEmpty){
                        result(resultData(data:[]))
                    }else{
                        var all:[[String:Any]] = allCredentials.map { c in
                             [
                                "networkName":c.networkName as Any,
                                "extendedPANID":c.extendedPANID?.toHex as Any,
                                "borderAgentID":c.borderAgentID?.toHex as Any,
                                "activeOperationalDataSet":c.activeOperationalDataSet?.toHex as Any,
                                "networkKey":c.networkKey?.toHex as Any,
                                "pskc":c.pskc?.toHex as Any,
                                "channel":c.channel as Any,
                                "panID":c.panID?.toHex as Any,
                            ]
                           
                        }
                        result(resultData(data:all))
                    }
                } catch {
                    print("Failure: \(error.localizedDescription)")
                    result(resultData(success:false, msg: error.localizedDescription, data: []))
                }
                
            }
        }else{
            result(resultData(success: false, msg: notSupport, data: []))
        }
    case "deleteCredentialsBy":
        if #available(iOS 15.0, *) {
            let arguments = call.arguments as! String
            guard let borderAgentID = arguments.hexadecimal else{
                return result(resultData(success: false, msg: dataError, data: false))
            }
            Task{
                let thClient = THClient()
                do {
                    try await thClient.deleteCredentials(forBorderAgent: borderAgentID)
                    result(resultData(data: true))
                } catch {
                    print("Failure: \(error.localizedDescription)")
                    result(resultData(success: false, msg: error.localizedDescription, data: false))
                }
                
            }
        }else{
            result(resultData(success: false, msg: notSupport, data: false))
        }
    case "storeCredentials":
        if #available(iOS 15.0, *) {
            let arguments = call.arguments as! [String:String]
            let agentID = arguments["borderAgentID"]
            let dataSet = arguments["activeDataSet"]
            print("agentID: \(String(describing: agentID))")
            print("dataSet: \(String(describing: dataSet))")
            guard let borderAgentID = agentID?.hexadecimal,
                  let activeDataSet = dataSet?.hexadecimal
            else{
                return result(resultData(success: false, msg: dataError, data: false))
            }
            Task{
                let thClient = THClient()
                do {
                    try await thClient.storeCredentials(
                        forBorderAgent: borderAgentID,
                        activeOperationalDataSet: activeDataSet
                    )
                    result(resultData(data: true))
                } catch {
                    print("Failure: \(error.localizedDescription)")
                    result(resultData(success: false, msg: error.localizedDescription, data: false))
                }
            }
        }else{
            result(resultData(success: false, msg: notSupport, data: false))
        }
    case "isPreferred":
        if #available(iOS 15.5, *) {
            let dataSet = call.arguments as! String
            guard let activeDataSet = dataSet.hexadecimal else{
                return result(resultData(success: false, msg: dataError, data: false))
            }
            Task{
                let thClient = THClient()
                let isPreferred = await thClient.isPreferred(forActiveOperationalDataset: activeDataSet)
                result(resultData(data: isPreferred))
            }
        }else{
            result(resultData(success: false, msg: notSupport, data: false))
        }
    default:
      result(FlutterMethodNotImplemented)

    }
  }
    
    func resultData(success:Bool = true,msg:String = "success",data:Any) -> [String:Any]{
        return ["success":success,"msg":msg,"data":data]
    }
}

#else

public class ThCredentialsManagerPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: "th_credentials_manager", binaryMessenger: registrar.messenger())
    let instance = ThCredentialsManagerPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    
    switch call.method {
    case "getPlatformVersion":
      result("iOS " + UIDevice.current.systemVersion)
    case "getAllCredentials":
        result(resultData(success: false, msg: notSupport, data: []))
    case "deleteCredentialsBy":
        result(resultData(success: false, msg: notSupport, data: false))
    case "storeCredentials":
        result(resultData(success: false, msg: notSupport, data: false))
    case "isPreferred":
        result(resultData(success: false, msg: notSupport, data: false))
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}
#endif
